package com.powermgr.boringtest.utils;

import lombok.extern.log4j.Log4j2;
import org.apache.tools.tar.TarEntry;
import org.apache.tools.tar.TarInputStream;

import java.io.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Objects;
import java.util.UUID;
import java.util.zip.GZIPInputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

/**
 * UnTarGzUtils
 *
 * @author qiuxiangdong
 * @date 2023/6/12
 */
@Log4j2
public class FileZipUtils {
    public static String uuidReportsName(){
        return UUID.randomUUID().toString().replaceAll("-", "");
    }
    public static String uuidTDD(){
        return "tdd_" + UUID.randomUUID().toString().replaceAll("-", "") + ".tar.gz";
    }
    public static String uuidXTS(){
        return "xts_" + UUID.randomUUID().toString().replaceAll("-", "") + ".tar.gz";
    }
    public static String uuidVersion(){
        return "version_" + UUID.randomUUID().toString().replaceAll("-", "") + ".tar.gz";
    }
    public static boolean unTarGzVersion(String version_name, String sn) {
        return FileZipUtils.unTarGz(ConfigUtils.PR_VERSION + File.separator + version_name,
                ConfigUtils.SN + File.separator + sn +  File.separator + "pr" + File.separator + "version");
    }
    public static boolean unTarGzTdd(String tdd_name, String sn) {
        return !FileZipUtils.unTarGz(ConfigUtils.PR_TDD + File.separator + tdd_name,
                ConfigUtils.SN + File.separator + sn + File.separator + "pr" + File.separator + "tdd");
    }
    public static boolean unTarGzXts(String xts_name, String sn) {
        return !FileZipUtils.unTarGz(ConfigUtils.PR_XTS + File.separator + xts_name,
                ConfigUtils.SN + File.separator + sn + File.separator + "pr" + File.separator + "xts");
    }
    public static boolean unTarGz(String sourceFile,String outputDir) {
        log.info("*开始解压：" + sourceFile);
        TarInputStream tarIn = null;
        File file = new File(sourceFile);
        try{
            tarIn = new TarInputStream(new GZIPInputStream(new BufferedInputStream(Files.newInputStream(file.toPath()))),
                    1024 * 2);
            createDirectory(outputDir,null);
            TarEntry entry = null;
            while( (entry = tarIn.getNextEntry()) != null ){
                if(entry.isDirectory()){//是目录
                    entry.getName();
                    createDirectory(outputDir,entry.getName());
                }else{//是文件
                    File tmpFile = new File(outputDir + File.separator + entry.getName());
                    createDirectory(tmpFile.getParent() + File.separator,null);
                    try (OutputStream out = Files.newOutputStream(tmpFile.toPath())) {
                        int length = 0;
                        byte[] b = new byte[2048];
                        while ((length = tarIn.read(b)) != -1) {
                            out.write(b, 0, length);
                        }
                    } catch (IOException ex) {
                        log.error("*解压异常", ex);
                        return false;
                    }
                }
            }
        }catch(IOException ex){
            log.error("*解压归档文件出现异常",ex);
            return false;
        } finally{
            try{
                if(tarIn != null){
                    tarIn.close();
                }
            }catch(IOException ex){
                log.error("*关闭tarFile出现异常");
            }
        }
        log.info("*解压完成：" + outputDir);
        return true;
    }
    private static void createDirectory(String outputDir,String subDir){
        File file = new File(outputDir);
        if(!(subDir == null || subDir.trim().isEmpty())){
            file = new File(outputDir + File.separator + subDir);
        }
        if(!file.exists()){
            if(!file.getParentFile().exists())
                file.getParentFile().mkdirs();
            file.mkdirs();
        }
    }
    public static void ToZip(String name, String sn) throws Exception {
        File sourceFile = new File(ConfigUtils.SN + File.separator + sn +  File.separator + "case"
                + File.separator + "developertest" + File.separator + "reports");

        if (!sourceFile.exists()) {
            throw new RuntimeException("不存在");
        }
        if (!sourceFile.isDirectory()) {
            throw new RuntimeException("不是文件夹");
        }
        //zip文件生成位置
        File zipFile = new File(ConfigUtils.PR_REPORTS + File.separator + name + ".zip");
        FileOutputStream fos = new FileOutputStream(zipFile);
        ZipOutputStream zos = new ZipOutputStream(new BufferedOutputStream(fos));
        fileToZip(zos, sourceFile, "");
        zos.close();
        fos.close();
    }
    private static void fileToZip(ZipOutputStream zos, File sourceFile, String path) throws Exception {
        if (sourceFile.isDirectory()) {
            path = path + sourceFile.getName() + "/";
            ZipEntry zipEntry = new ZipEntry(path);
            zos.putNextEntry(zipEntry);
            for (File file : Objects.requireNonNull(sourceFile.listFiles())) {
                fileToZip(zos, file, path);
            }
        } else {
            ZipEntry zipEntry = new ZipEntry(path + sourceFile.getName());
            zos.putNextEntry(zipEntry);
            byte[] bufs = new byte[1024 * 10];
            FileInputStream fis = new FileInputStream(sourceFile);
            BufferedInputStream bis = new BufferedInputStream(fis, 1024 * 10);
            int read = 0;
            while ((read = bis.read(bufs, 0, 1024 * 10)) != -1) {
                zos.write(bufs, 0, read);
            }
            bis.close();
            fis.close();
        }
    }

    public static void createFile(String path){
        File dir = new File(path);
        boolean result = dir.mkdirs();
        if(result) {
            log.info("*createFile：" + path);
        } else {
            log.error("*createFile：文件已经存在 " + path);
        }
    }

    public static void deleteFile(String path) {
        File directory = new File(path);
        log.info("*deleteFile: 删除 " + path);
        deleteDirectory(directory);
    }
    private static void deleteDirectory(File directory) {
        if (directory.exists()) {
            if(directory.isDirectory()) {
                File[] files = directory.listFiles();
                if(files != null) {
                    for(File file : files) {
                        deleteDirectory(file);
                    }
                }
                boolean delete = directory.delete();
            } else {
                boolean delete = directory.delete();
            }
        } else {
            log.error("deleteFile：文件不存在 " + directory);
        }
    }
}
